/*
 * FileName：UserCtrl.java
 * <p>
 * Copyright (c) 2017-2020 <a href="https://www.smartwx.info">hermit(1154808491@qq.com)</a>.
 * <p>
 * Licensed under the GNU General Public License, Version 3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/gpl-3.0.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package com.smart.primary.sys.ctrl;

import com.google.common.collect.ImmutableMap;
import com.smart.common.BaseCtrl;
import com.smart.common.Constants;
import com.smart.common.util.*;
import com.smart.primary.config.AsyncFactory;
import com.smart.sys.entity.SysLoginInfo;
import com.smart.sys.entity.SysMenu;
import com.smart.sys.entity.SysUser;
import com.smart.sys.entity.SysUserRole;
import com.smart.sys.service.ISysMenuService;
import com.smart.sys.service.ISysUserRoleService;
import com.smart.sys.service.ISysUserService;
import com.smart.wx.wxcms.entity.Account;
import com.smart.wx.wxcms.service.AccountService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.WebUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author hermit
 * @version 2.0
 * @date 2018-04-17 10:54:58
 */
@RestController
@RequestMapping("user")
@Api(description = "常规操作")
public class UserCtrl extends BaseCtrl {

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysMenuService sysMenuService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private ISysUserRoleService sysUserRoleService;

    @Autowired
    private AsyncFactory asyncFactory;

    @PostMapping(value = "/login")
    @ApiOperation(value = "login")
    public AjaxResult login(SysUser user)
            throws Exception {
        user.setPassword(MD5Util.getMD5Code(user.getPassword()));
        user.setDelFlag(Constants.DEL_FLAG_NORMAL);
        SysUser sysUser = this.sysUserService.queryObject(user);
        if (sysUser == null) {
            asyncFactory.insertLoginInfo(SysLoginInfo.builder().account(user.getAccount()).msg("用户名或者密码错误").status(Constants.FAIL_FLAG).build(), request);
            return AjaxResult.failure("用户名或者密码错误");
        }
        if (Constants.STATE_DISABLE.equals(sysUser.getStatus())) {
            asyncFactory.insertLoginInfo(SysLoginInfo.builder().account(user.getAccount()).msg("对不起，账号已过期，请及时购买正版").status(Constants.FAIL_FLAG).build(), request);
            return AjaxResult.failure("对不起，账号已过期，请及时购买正版");
        }
        if (Constants.STATE_LOCK.equals(sysUser.getStatus())) {
            asyncFactory.insertLoginInfo(SysLoginInfo.builder().account(user.getAccount()).msg("对不起，账号已锁定，请联系管理员").status(Constants.FAIL_FLAG).build(), request);
            return AjaxResult.failure("对不起，账号已锁定，请联系管理员");
        }
        if (Constants.STATE_DISABLE.equals(sysUser.getStatus())) {
            asyncFactory.insertLoginInfo(SysLoginInfo.builder().account(user.getAccount()).msg("对不起，账号已禁用，请联系管理员").status(Constants.FAIL_FLAG).build(), request);
            return AjaxResult.failure("对不起，账号已禁用，请联系管理员");
        }
        //查找权限内容
        List<SysMenu> objectList = sysMenuService.getMenuList(SysUserRole.builder().userId(sysUser.getUserId()).build());
        if (CollectionUtils.isEmpty(objectList)) {
            asyncFactory.insertLoginInfo(SysLoginInfo.builder().account(user.getAccount()).msg("对不起，您没有任何权限，请联系管理员").status(Constants.FAIL_FLAG).build(), request);
            return AjaxResult.failure("对不起，您没有任何权限，请联系管理员");
        }
        //异步添加登陆日志
        SessionUtil.setUser(sysUser);
        asyncFactory.insertLoginInfo(SysLoginInfo.builder().account(user.getAccount()).status(Constants.SUCESS_FLAG).build(), request);
        //设置登陆者默认公众号
        Account account = accountService.getSingleAccount(sysUser.getUserId());
        if (null != account) {
            SessionUtil.setAttr(Constants.SESSION_ACCOUNT, account.getAccount());
        }
        return AjaxResult.success(ImmutableMap.of("account", sysUser.getAccount(), "avatar", sysUser.getAvatar()));
    }

    /**
     * 用户修改密码
     *
     * @param user
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/updatepwd")
    @ApiOperation(value = "用户修改密码")
    public AjaxResult updatepwd(SysUser user)
            throws Exception {
        if (!SessionUtil.getUser().getPassword().equals(MD5Util.getMD5Code(user.getPassword()))) {
            return AjaxResult.failure("原密码错误");
        }
        user.setUserId(SessionUtil.getUserId());
        user.setPassword(MD5Util.getMD5Code(user.getNewPassword()));
        this.sysUserService.update(user);
        // 注销用户
        request.getSession().invalidate();
        return AjaxResult.success();
    }

    /**
     * 用户修改个人信息
     *
     * @param user
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/update")
    @ApiOperation(value = "用户修改个人信息")
    public AjaxResult update(SysUser user)
            throws Exception {
        user.setUserId(SessionUtil.getUserId());
        this.sysUserService.update(user);
        //更改緩存
        SessionUtil.setUser(sysUserService.queryObject(SysUser.builder().userId(SessionUtil.getUserId()).build()));
        return AjaxResult.success();
    }

    /**
     * 查询个人信息
     *
     * @return
     */
    @GetMapping("info")
    @ApiOperation(value = "查询个人信息")
    public AjaxResult info() {
        SysUser user = SessionUtil.getUser();
        if (null == user) {
            return AjaxResult.failure();
        }
        return AjaxResult.success(SysUser.builder().account(user.getAccount()).avatar(user.getAvatar()).build());
    }

    /**
     * 用户退出
     *
     * @return
     */
    @PostMapping("logout")
    @ApiOperation(value = "用户退出")
    public AjaxResult logout(HttpServletRequest request, HttpServletResponse response) {
        request.getSession().invalidate();
        return AjaxResult.success();
    }

    /**
     * 用户注册
     *
     * @return
     */
    @PostMapping("register")
    @ApiOperation(value = "用户注册")
    public AjaxResult register(SysUser user, String verificationCode, String userEmailCode) throws Exception {
        if (StringUtil.isBlank(user.getAccount()) || StringUtil.isBlank(user.getPassword()) || StringUtil.isBlank(verificationCode) || StringUtil.isBlank(userEmailCode)) {
            return AjaxResult.failure("输入不完整");
        }
        if (!WebUtils.getSessionAttribute(request, Constants.SESSION_VERIFY_CODE).equals(StringUtil.upperCase(verificationCode))) {
            return AjaxResult.failure("图形验证码错误");
        }
        if (!WebUtils.getSessionAttribute(request, Constants.SESSION_MAIL_CODE).equals(StringUtil.upperCase(userEmailCode))) {
            return AjaxResult.failure("邮箱验证码错误");
        }
        //判断是否登录名重复
        Integer count = sysUserService.queryCount(user);
        if (count != null && count > 0) {
            return AjaxResult.failure("用户名重复");
        }
        user.setDeptId(Constants.CUSTOMER_DEPT_ID);
        if (PropertiesUtil.getBoolean("demoMode")) {
            user.setUserType(Constants.TEMP_USER_TYPE);
        }
        Integer conunt = sysUserService.insert(user);
        //插入角色
        if (conunt > 0) {
            sysUserRoleService.insert(SysUserRole.builder()
                    .roleId(Constants.CUSTOMER_ROLE_ID)
                    .userId(user.getUserId())
                    .build());
        }
        return AjaxResult.success();
    }

    /**
     * 用户注册-发送邮箱验证码
     *
     * @return
     */
    @PostMapping("sendmail")
    @ApiOperation(value = " 用户注册-发送邮箱验证码")
    public AjaxResult sendMail(SysUser user, String verificationCode) throws Exception {
        if (StringUtil.isBlank(user.getAccount()) || StringUtil.isBlank(verificationCode) || null == WebUtils.getSessionAttribute(request, Constants.SESSION_VERIFY_CODE)) {
            return AjaxResult.failure("参数不正确，请重新输入");
        }
        if (!ValidateUtil.isEmail2(StringUtil.lowerCase(user.getAccount()))) {
            return AjaxResult.failure("请输入正确的qq邮箱");
        }
        if (!WebUtils.getSessionAttribute(request, Constants.SESSION_VERIFY_CODE).equals(StringUtil.upperCase(verificationCode))) {
            return AjaxResult.failure("验证码错误");
        }
        //判断是否登录名重复
        Integer count = sysUserService.queryCount(user);
        if (count != null && count > 0) {
            return AjaxResult.failure("用户名重复");
        }
        //生成验证码
        String code = Util.bulidMobileCode(6);
        WebUtils.setSessionAttribute(request, Constants.SESSION_MAIL_CODE, code);
        MailUtil.sendMail(user.getAccount(), "smart-admin验证码", "尊敬的用户您好,您本次注册的验证码是: " + code);
        return AjaxResult.success();
    }
}
